package editorsvg.editor.serializacion;

import editorsvg.editor.documento.Documento;
import editorsvg.editor.documento.ElementoEditable;
import editorsvg.editor.documento.ElementoSVG;
import editorsvg.editor.documento.PrototipoElemento;
import editorsvg.propiedades.DefinicionPropiedades;
import editorsvg.propiedades.Propiedad;
import java.io.File;
import java.io.FileReader;
import java.util.Deque;
import java.util.LinkedList;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/**
 *
 * @author Jorge Berjano
 */
public class LectorSVG extends DefaultHandler {

    private XMLReader xmlReader;
    private Documento documento;
    private Deque<ElementoSVG> rutaActual = new LinkedList<ElementoSVG>();

    public LectorSVG() throws SAXException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setValidating(false);
        factory.setSchema(null);

        try {
            xmlReader = factory.newSAXParser().getXMLReader();
        } catch (ParserConfigurationException ex) {
            System.err.println("No se ha podido obtener el lector xml: " + ex.getMessage());
            return;
        }

        xmlReader.setContentHandler(this);
        xmlReader.setErrorHandler(this);
    }

    public Documento leer(String nombreArchivo) throws Exception {
        return leer(new File(nombreArchivo));
    }
    
    public Documento leer(File archivo) throws Exception {
        if (xmlReader == null) {
            return null;
        }
        FileReader fileReader = new FileReader(archivo);
        xmlReader.parse(new InputSource(fileReader));
        return documento;
    }

    @Override
    public void startDocument() {
        System.out.println("Comienzo del Documento XML");
    }

    @Override
    public void endDocument() {
        System.out.println("Final del Documento XML");
    }

    @Override
    public void startElement(String uri, String name, String qName, Attributes atts) {

        ElementoSVG elemento = PrototipoElemento.crearElemento(name);

        if (elemento instanceof Documento) {
            documento = (Documento) elemento;
        }

        if (elemento != null) {            
            cargarAtributos(elemento, atts);
            agregarAlActual(elemento);
        }
        
        entrarEnElemento(elemento);
    }
    
    @Override
    public void characters (char ch[], int start, int length) {
        elementoActual().agregarTexto(new String(ch, start, length));
    }

    @Override
    public void endElement(String uri, String name, String qName) {
        salirDelElemento();
    }

    private void agregarAlActual(ElementoSVG elemento) {
        if (elemento == null) {
            return;
        }
        ElementoSVG actual = elementoActual();
        
        if (actual instanceof ElementoEditable) {
            ElementoEditable editable = (ElementoEditable) actual;
            editable.agregarElemento(elemento);
        }
    }

    private void entrarEnElemento(ElementoSVG elemento) {
        rutaActual.offerLast(elemento);
    }

    private void salirDelElemento() {
        rutaActual.pollLast();
    }
    
    
    /**
     * Carga los atributos en el elementoSVG
     */
    private void cargarAtributos(ElementoSVG elemento, Attributes atts) {
        DefinicionPropiedades propiedades = elemento.getPropiedades();

        for (int i = 0; i < atts.getLength(); i++) {
            Propiedad propiedad = propiedades.obtenerPropiedadAtributoXml(atts.getLocalName(i));            
            if (propiedad != null) {
                propiedad.parsearPropiedad(atts.getValue(i));
            }
        }
        
        
    }

    private ElementoSVG elementoActual() {        
        return rutaActual.peekLast();
    }
}
